package cn.kent.repo;

import cn.kent.entity.Ingredient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author kent
 * @Repository 注解：Spring定义了一系列的构造型注解stereotype， 还有@Component和@Controller都是
 * Spring扫描会自动发现它，并初始化为Spring应用上下文中的bean。
 * @date 2021/5/27 16:57
 */
@Repository
public class JdbcIngredientRepository implements IngredientRepository {

    private JdbcTemplate jdbc;

    /**
     * 构造器注入
     * 这个构造器将JdbcTemplate赋值给一个实例变量，这个变量会被其他方法用来执行数据库查询和插入操作。
     *
     * @param jdbc template
     */
    @Autowired
    public JdbcIngredientRepository(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    @Override
    public Iterable<Ingredient> finAll() {
        return jdbc.query("select id, name, type from Ingredient",
                this::mapRowToIngredient);
    }

    private Ingredient mapRowToIngredient(ResultSet rs, int i) throws SQLException {
        return new Ingredient(
                rs.getString("id"),
                rs.getString("name"),
                Ingredient.Type.valueOf(rs.getString("type"))
        );
    }

    @Override
    public Ingredient findOne(String id) {
        return jdbc.queryForObject("select id, name, type from Ingredient where id=?",
                this::mapRowToIngredient, id);
    }

//    /**
//     * java8的方法引用和lambda表达式非常便利，他们能够替代显式的RowMapper实现。
//     * 如果非要用RowMapper实现-->以下是RowMapper的实现
//     */
//    @Override
//    public Ingredient findOne(String id) {
//        return jdbc.queryForObject("select id, name, type from Ingredient where id=?",
//                new RowMapper<Ingredient>() {
//                    @Override
//                    public Ingredient mapRow(ResultSet rs, int i) throws SQLException {
//                        return new Ingredient(Long.valueOf(rs.getString("id")),
//                                rs.getString("name"),
//                                Ingredient.Type.valueOf(rs.getString("type")));
//                    };
//                }, id);
//    }

    @Override
    public Ingredient save(Ingredient ingredient) {
        jdbc.update(
                "insert into Ingredient (id,name,type) values(?,?,?)",
                ingredient.getId(),
                ingredient.getName(),
                ingredient.getType().toString()
        );
        return ingredient;
    }
}
